package cn.com.libertymutual.core.xml;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class MapAdapter extends XmlAdapter<Object, Map<String,Object>>{

	@Override
	public Map<String, Object> unmarshal(Object v) throws Exception {
		// TODO Auto-generated method stub
		//Map<String,Object> map = new HashMap<String,Object>();
		
		Element ele = (Element) v;
		/*NodeList nodeList = ele.getChildNodes();
		int len = nodeList.getLength();
		for( int i=0; i<len; i++ ) {
			Element et = (Element) nodeList.item(i);
			System.out.println( et.getChildNodes() );
			map.put(et.getNodeName(), et.getTextContent());
		}
		*/
		return elementConvertToMap(ele);
		
		//return map;
	}

	@Override
	public Object marshal(Map<String, Object> map) throws Exception {
		// TODO Auto-generated method stub
		if( map == null ) return null;
		
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document document = builder.newDocument();
		Element rootEle = document.createElement("PUBREQBODY");
		
		/*Iterator<Entry<String,Object>> it = map.entrySet().iterator();
		while( it.hasNext() ) {
			Entry<String, Object> entry = it.next();
			Element ele = document.createElement(entry.getKey());
			Object value = entry.getValue();
			if( value != null ) {
				if( value instanceof String )
					ele.setTextContent( (String)value );
				else if( value instanceof HashMap ) {
					
				}
			}
			
			rootEle.appendChild(ele);
		}*/
		createElement(document, rootEle, map);
		
		return rootEle;
	}

	private Map<String,Object> elementConvertToMap( Element ele ) {
		Map<String,Object> map = new HashMap<String, Object>();

		NodeList nodeList = ele.getChildNodes();
		int len = nodeList.getLength();
		for( int i=0; i<len; i++ ) {
			Node node = nodeList.item(i);
			//System.out.println(node.getClass());
			//Node et = (Node)obj;
			
			if( node != null && node.getNodeType() == Element.ELEMENT_NODE ) {
				Element et = (Element) node;
				
				//System.out.println(et.getNodeName()+"\t"+et.getFirstChild().getNodeType());
				
				if( et.getFirstChild().getNodeType() == Element.ELEMENT_NODE ) {
					//map.put(et.getNodeName(), elementConvertToMap( et ) );
					map.put(et.getLocalName(), elementConvertToMap( et ) );
				}
				else {
					//System.out.println(et.getLocalName());
					//map.put(et.getNodeName(), et.getTextContent() );
					map.put(et.getLocalName(), et.getNodeValue() );
				}
			}
			else {
				//System.out.println(((Element)obj).getNodeName());
				//System.out.println(node.getClass());
				Text et = (Text) node;
				//System.out.println(et.get);
				//System.out.println( et.getParentNode().getNodeName());
				if( et != null && et.getParentNode() != null )
					map.put(et.getParentNode().getNodeName(), et.getNodeValue());
			}
		}
		
		return map;
	}
	
	@SuppressWarnings("unchecked")
	private void createElement( Document document, Element rootEle, Map<String, Object> map) {
		Iterator<Entry<String,Object>> it = map.entrySet().iterator();
		while( it.hasNext() ) {
			Entry<String, Object> entry = it.next();
			Element ele = document.createElement(entry.getKey());
			Object value = entry.getValue();
			if( value != null ) {
				if( value instanceof String )
					//ele.setTextContent( (String)value );
					ele.setNodeValue( (String)value );
				else if( value instanceof HashMap ) {
					createElement(document, ele, (Map<String,Object>)value);
				}
			}
			
			rootEle.appendChild(ele);
		}
	}

}
